#include "stdafx.h"
#include "UIFromToByAnimation.h"

namespace DirectUI
{
	namespace UIAnimation
	{
		CUIDoubleAnimation::CUIDoubleAnimation()
		{

		}

		CUIDoubleAnimation::~CUIDoubleAnimation()
		{

		}

		void CUIDoubleAnimation::OnParseAttribute( xml_attribute& attr, LPCTSTR lpAttrAlias )
		{
			CString szAttrName = attr.name();
			CString szVal = attr.value();

			if ( szAttrName.CollateNoCase(_T("From")) == 0 )
				szAttrName = _T("From_Double");
			else if ( szAttrName.CollateNoCase(_T("To")) == 0 )
				szAttrName = _T("To_Double");
			else if ( szAttrName.CollateNoCase(_T("By")) == 0 )
				szAttrName = _T("By_Double");

			__super::OnParseAttribute(attr, szAttrName);
		}

		bool CUIDoubleAnimation::CheckValid()
		{
			double From = GetProperty(From_Double)->GetDoubleValue();
			double To = GetProperty(To_Double)->GetDoubleValue();
			double By = GetProperty(By_Double)->GetDoubleValue();
			if ( From == To || (To-From)*By < 0 )
			{
				assert(false);
				return false;
			}

			UITIMESPAN dur = GetProperty(Duration)->GetTimeSpanValue()/10000;
			assert(dur>0);
			if ( dur <= 0 )
				return false;

			return true;
		}

		void CUIDoubleAnimation::OnComplete()
		{
			int a = 0;
		}

		void CUIDoubleAnimation::OnTaskInit( CUIAnimationTimerData* pData )
		{
			m_pTimerTaskData = pData;
			if ( m_pTimerTaskData->m_spTagElement )
				ChangeDoubleProperty(m_pTimerTaskData->m_spOwner->GetProperty(From_Double)->GetDoubleValue());
		}

		BOOL CUIDoubleAnimation::DoTimerTask()
		{
			CUIDoubleAnimation* p = (CUIDoubleAnimation*)(IUITimeline*)m_pTimerTaskData->m_spOwner;
			UITIMESPAN ElapseTime = GetTickCount()-m_pTimerTaskData->m_StartTime;
			double From = p->GetProperty(From_Double)->GetDoubleValue();
			double To = p->GetProperty(To_Double)->GetDoubleValue();
			double By = p->GetProperty(By_Double)->GetDoubleValue();
			UITIMESPAN dur = p->GetProperty(Duration)->GetTimeSpanValue()/10000;
			UIPropertyName uElementPropertyName = (UIPropertyName)(p->GetProperty(TargetProperty)->GetIntValue());
			CUIObjectPtr<IUIProperty> spProperty = m_pTimerTaskData->m_spTagElement->GetProperty(uElementPropertyName);
			if ( !spProperty )
			{
				assert(false);
			}
			double now = spProperty->GetDoubleValue();

			BOOL bEnd = ElapseTime+p->GetTimerSpan() >= dur;

			double show_now = bEnd ? To : (To-From)*ElapseTime/dur+From;
			spProperty->SetDoubleValue(show_now);

			return bEnd;
		}

		void CUIDoubleAnimation::ChangeDoubleProperty( double value )
		{
			if ( !m_pTimerTaskData->m_spTagElement )
				return;
			CUIDoubleAnimation* p = (CUIDoubleAnimation*)(IUITimeline*)m_pTimerTaskData->m_spOwner;
			UIPropertyName uElementPropertyName = (UIPropertyName)(p->GetProperty(TargetProperty)->GetIntValue());
			CUIObjectPtr<IUIProperty> spProperty = m_pTimerTaskData->m_spTagElement->GetProperty(uElementPropertyName);
			if ( !spProperty )
			{
				assert(false);
				return;
			}
			spProperty->SetDoubleValue(value);
		}

		//////////////////////////////////////////////////////////////////////////
		CUIColorAnimation::CUIColorAnimation()
		{

		}

		CUIColorAnimation::~CUIColorAnimation()
		{
			int a = 0;
		}

		bool CUIColorAnimation::CheckValid()
		{
			UICOLOR From = GetProperty(From_Color)->GetColorValue();
			UICOLOR To = GetProperty(To_Color)->GetColorValue();
			UICOLOR By = GetProperty(By_Color)->GetColorValue();
			if ( From == To || (To-From)*By < 0 )
			{
				assert(false);
				return false;
			}

			UITIMESPAN dur = GetProperty(Duration)->GetTimeSpanValue()/10000;
			assert(dur>0);
			if ( dur <= 0 )
				return false;

			return true;
		}

		void CUIColorAnimation::OnComplete()
		{

		}

		void CUIColorAnimation::OnParseAttribute( xml_attribute& attr, LPCTSTR lpAttrAlias )
		{
			CString szAttrName = attr.name();
			CString szVal = attr.value();

			if ( szAttrName.CollateNoCase(_T("From")) == 0 )
				szAttrName = _T("From_Color");
			else if ( szAttrName.CollateNoCase(_T("To")) == 0 )
				szAttrName = _T("To_Color");
			else if ( szAttrName.CollateNoCase(_T("By")) == 0 )
				szAttrName = _T("By_Color");

			__super::OnParseAttribute(attr, szAttrName);
		}

		void CUIColorAnimation::OnTaskInit( CUIAnimationTimerData* pData )
		{
			m_pTimerTaskData = pData;
			if ( m_pTimerTaskData->m_spTagElement )
				ChangeColorProperty(m_pTimerTaskData->m_spOwner->GetProperty(From_Color)->GetColorValue());
		}

		BOOL CUIColorAnimation::DoTimerTask()
		{
			CUIDoubleAnimation* p = (CUIDoubleAnimation*)(IUITimeline*)m_pTimerTaskData->m_spOwner;
			UITIMESPAN ElapseTime = GetTickCount()-m_pTimerTaskData->m_StartTime;
			Gdiplus::Color From = p->GetProperty(From_Color)->GetColorValue();
			Gdiplus::Color To = p->GetProperty(To_Color)->GetColorValue();
			Gdiplus::Color By = p->GetProperty(By_Color)->GetColorValue();
			UITIMESPAN dur = p->GetProperty(Duration)->GetTimeSpanValue()/10000;
			UIPropertyName uElementPropertyName = (UIPropertyName)(p->GetProperty(TargetProperty)->GetIntValue());
			CUIObjectPtr<IUIProperty> spProperty = m_pTimerTaskData->m_spTagElement->GetProperty(uElementPropertyName);
			if ( !spProperty )
			{
				assert(false);
			}
			UICOLOR now = spProperty->GetColorValue();

			BOOL bEnd = ElapseTime+p->GetTimerSpan() >= dur;

			Gdiplus::Color clrRet;
	
#define X_CLR(x) (BYTE)(((int)(To.x())-(int)(From.x()))*ElapseTime/dur+(int)(From.x()))
			BYTE a = X_CLR(GetAlpha);
			BYTE r = X_CLR(GetRed);
			BYTE g = X_CLR(GetGreen);
			BYTE b = X_CLR(GetBlue);
			UICOLOR show_now = bEnd ? To.GetValue() : Gdiplus::Color(a, r, g, b).GetValue();
			spProperty->SetColorValue(show_now);

			return bEnd;
		}

		void CUIColorAnimation::ChangeColorProperty( UICOLOR value )
		{
			if ( !m_pTimerTaskData->m_spTagElement )
				return;
			CUIColorAnimation* p = (CUIColorAnimation*)(IUITimeline*)m_pTimerTaskData->m_spOwner;
			UIPropertyName uElementPropertyName = (UIPropertyName)(p->GetProperty(TargetProperty)->GetIntValue());
			CUIObjectPtr<IUIProperty> spProperty = m_pTimerTaskData->m_spTagElement->GetProperty(uElementPropertyName);
			if ( !spProperty )
			{
				assert(false);
				return;
			}
			spProperty->SetColorValue(value);
		}

	}
}